
/* server.c — 简单的 TCP 服务器 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include "protocol.h"
#include <errno.h>
#include "common.h"

#define PORT 8888      // 监听端口
#define BACKLOG 5      // 未接受连接队列长度
#define BUF_SIZE 4096  // 缓冲区大小





void receive_file(int conn_fd, const char *out_path)
{
    FILE *fp = fopen(out_path, "wb");
    if (!fp) {
        perror("fopen");
        return;
    }

    uint8_t buffer[BUF_SIZE];
    ssize_t n;

    // 不断从 conn_fd 读数据，直到对端关闭（recv 返回 0）或出错
    while ((n = recv(conn_fd, buffer, sizeof(buffer), 0)) > 0) {
        // 将接收到的 n 字节写到文件里
        size_t written = fwrite(buffer, 1, n, fp);
        if (written != (size_t)n) {
            perror("fwrite");
            break;
        }
    }
    if (n < 0) {
        perror("recv");
    }

    fclose(fp);
    printf("File received and saved to %s\n", out_path);
}






int send_and_recv_ack(int sock_fd,
                      uint16_t msgType,
                      const uint8_t *data,
                      uint16_t dataLen)
{
    uint8_t  buf[BUF_SIZE];
    // 1. 打包
    int pktLen = build_packet(msgType, data, dataLen, buf, BUF_SIZE);
    if (pktLen < 0) {
        fprintf(stderr, "build_packet error: %d\n", pktLen);
        return -1;
    }

    my_print_hex(buf, pktLen);

    // 2. 发送
    if (send(sock_fd, buf, pktLen, 0) != pktLen) {
        perror("send");
        return -2;
    }

    printf("W --- 111111111111\n");
    // // 3. 等待 ACK
    // ssize_t n = recv(sock_fd, buf, BUF_SIZE, 0);
    // printf("W --- 33333333333333\n");
    // if (n < 0) {
    //     perror("recv");
    //     printf("recv error: %s\n", strerror(errno));
    //     return -3;
    // } else if (n == 0) {
    //     fprintf(stderr, "connection closed by peer server\n");
    //     return -4;
    // }
    // printf("W --- 22222222222222222\n");

    // // 4. 解析 ACK
    // uint16_t respType, respLen;
    // uint8_t  respData[BUF_SIZE];
    // int ret = parse_packet(&respType, respData, &respLen, buf, (size_t)n);
    // if (ret < 0) {
    //     fprintf(stderr, "parse_packet error: %d\n", ret);
    //     return -5;
    // }
    // if (respType != 0x8001) {
    //     fprintf(stderr, "unexpected respType: 0x%04X\n", respType);
    //     return -6;
    // }

    // // 打印 ACK 内容
    // printf("收到 ACK(type=0x8001, len=%u): %.*s\n",
    //        respLen, respLen, respData);

    // return respLen;
}






int cmd_engine(int fd)
{
    // 1/录文件
    // 2 上传文件

    int cmd = 0;

    while (1)
    {
        printf("please input: ");
        scanf("%d", &cmd);
        printf("cmd: %d\n", cmd);

        switch (cmd)
        {
            case 1:
            {
                // @todo 发送录音指令
                printf("发送录音指令\n");
                uint8_t data = 0x01;
                uint16_t msgType   = 0x0001;
            
                int ackLen = send_and_recv_ack(fd,
                                                msgType,
                                               &data,
                                               sizeof(data));
                if (ackLen < 0) {
                    fprintf(stderr, "protocol exchange failed: %d\n", ackLen);
                }

                break;
            }
            case 2:
            {
                // @todo 上传文件
                printf("上传文件\n");

                uint8_t data = 0x02;
                uint16_t msgType   = 0x0001;
            
                int ackLen = send_and_recv_ack(fd,
                                                msgType,
                                               &data,
                                               sizeof(data));

                                               
                // 让客户端把数据当“一个完整文件”一次性发过来
                receive_file(fd, "received_from_client.wav");
                
                printf("okok\n");

                // 发送回执
                const char *reply = "File received successfully!";
                send(fd, reply, strlen(reply), 0);



                // if (ackLen < 0) {
                //     fprintf(stderr, "protocol exchange failed: %d\n", ackLen);
                // }

                
                break;
            }
            default:
                printf("unkonw cmd[%d]\n", cmd);
                break;
        }
    } 
    
}






int main() {

    int listen_fd, conn_fd;
    struct sockaddr_in serv_addr, cli_addr;
    socklen_t cli_len = sizeof(cli_addr);
    
     

    // 1. 创建套接字
    if ((listen_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        perror("socket");
        exit(EXIT_FAILURE);
    }

    // 2. 绑定地址和端口
    memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;  // 本机所有 IP
    serv_addr.sin_port = htons(PORT);        // 网络字节序

    int on = 1;
    setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) );

    if (bind(listen_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
        perror("bind");
        close(listen_fd);
        exit(EXIT_FAILURE);
    }

    // 3. 开始监听
    if (listen(listen_fd, BACKLOG) < 0) {
        perror("listen");
        close(listen_fd);
        exit(EXIT_FAILURE);
    }

    printf("Server listening on port %d...\n", PORT);

    // 4. 接受连接
    if ((conn_fd = accept(listen_fd, (struct sockaddr*)&cli_addr, &cli_len)) < 0) {
        perror("accept");
        close(listen_fd);
        exit(EXIT_FAILURE);
    }

    printf("Accepted connection from %s:%d\n",
           inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port));

    // // // // 5. 通信：接收客户端消息并回送
    // // // while ((n = recv(conn_fd, buffer, BUF_SIZE - 1, 0)) > 0) {
    // // //     buffer[n] = '\0';
    // // //     // printf("Received from client: %s\n", buffer);
    // // //     printf("Received from client: \n");
    // // //     show_hex(buffer,n);


    // // //     const char *reply = "Hello from server!";
    // // //     send(conn_fd, reply, strlen(reply), 0);
    // // // }

    // // // 让客户端把数据当“一个完整文件”一次性发过来
    // // receive_file(conn_fd, "received_from_client.wav");
    
    // // printf("okok\n");

    // // // 发送回执
    // // const char *reply = "File received successfully!";
    // // send(conn_fd, reply, strlen(reply), 0);


    // // if (n < 0) perror("recv");

    // 调用协议层打包
    // 示例：发送单字节 0x01，msgType=0x0001
    cmd_engine(conn_fd);

    // 6. 关闭连接
    close(conn_fd);
    close(listen_fd);
    return 0;
}



